import Axios from 'axios'
import router from '@/router'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
interface myConfig extends AxiosRequestConfig {
  token?: boolean
}

type Result<T> = {
  code: number,
  msg: string,
  data: T
}


class Request {
  private instance: AxiosInstance
  public baseConfig: AxiosRequestConfig = { baseURL: '/api', timeout: 60 * 100 }
  private loadInstance: any
  constructor(config: AxiosRequestConfig) {
    this.instance = Axios.create(Object.assign(this.baseConfig, config))
    this.instance.interceptors.request.use((config: myConfig) => {
      this.loadInstance = ElLoading.service({ lock: true })
      if (config.token) {
        let userInfo = localStorage.getItem('user') as string
        userInfo = JSON.parse(userInfo)
        config.headers!.token = (userInfo as unknown as any).token || ''

      }
      return config
    }, (err: any) => Promise.reject(err))

    this.instance.interceptors.response.use((res: AxiosResponse) => {
      this.loadInstance.close()
      return res
    }, (err: any) => {
      this.loadInstance.close()
      const res: AxiosResponse = err.response
      if (res.status !== 200 && res.data.msg === 'fail') {
        switch (res.data.data) {
          case 'Token 令牌不合法!':
            ElMessage({
              message: '登录失效,请重新登录',
              type: "warning"
            })
            localStorage.clear()
            router.push('/login')
            break
          default:
            ElMessage({
              message: res.data.data,
              type: "warning"
            })
            return Promise.reject(res.data.data)
        }
      }
      return Promise.reject(err.response)
    })
  }

  public request<T = any>(config: myConfig): Promise<AxiosResponse<Result<T>>> {
    return this.instance.request(config)
  }

  public get<T = any>(url: string, config?: myConfig): Promise<AxiosResponse<Result<T>>> {
    return this.instance.get(url, config)
  }

  public post<T = any>(url: string, data?: any, config?: myConfig): Promise<AxiosResponse<Result<T>>> {
    return this.instance.post(url, data, config)
  }

  public put<T = any>(url: string, data?: any, config?: myConfig): Promise<AxiosResponse<Result<T>>> {
    return this.instance.put(url, data, config)
  }

  public delete<T = any>(url: string, config?: myConfig): Promise<AxiosResponse<Result<T>>> {
    return this.instance.delete(url, config)
  }
}

export default new Request({})